/**
 * 
 */
package com.hww.Reflect;

import java.lang.reflect.*;

/**
 * @author:huangwenwei
 * @date:2014-4-29
 * @time:下午5:54:47
 */
/**
 * @author:huangwenwei
 * @date:2014-4-29 
 * @time:下午9:08:39
 */
/**
 * @author:huangwenwei
 * @date:2014-4-29 
 * @time:下午9:08:43
 */
public class ReflectDemo {

	/**
	 * @param args
	 *            void
	 * @throws InstantiationException 
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws NoSuchMethodException 
	 * @throws SecurityException 
	 * @throws NoSuchFieldException 
	 */
	public static void main(String[] args) throws ClassNotFoundException,
			IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException, InstantiationException, NoSuchFieldException, SecurityException {
		System.out.println("demo1:通过Java反射机制得到类的包名和类名");
		demo1();
		
		System.out.println("");
		System.out.println("demo2:验证所有类都是Class类的实例对象");
		demo2();
		
		System.out.println("");
		System.out.println("demo3:通过Java反射机制，用class创建类对象，这也就是反射存在的意义所在");
		demo3();
		
		System.out.println("");
		System.out.println("demo4:通过反射机制得到一个类的构造方法，并实现创建带实例的对象");
		demo4();
		
		System.out.println("");
		System.out.println("demo5:通过Java反射机制操作成员变量，set和get");
		demo5();
		
		System.out.println("");
		System.out.println("demo6:通过反射机制得到类的一些属性：继承的接口、父类、方法信息、成员信息、类型等");
		demo6();
		
		System.out.println("");
		System.out.println("demo7:通过Java反射机制调用类方法");
		demo7();
		
		System.out.println("");
		System.out.println("demo8：通过Java反射机制得到加载器信息");
		demo8();
	}
	
	/**
	 * demo1 通过反射机制得到类的包名和类名
	 *   void
	 */
	public static void demo1(){
		Person person = new Person();
		System.out.println("包名：" + person.getClass().getPackage().getName());
		System.out.println("完整类名：" + person.getClass().getName());
	}
	

	/**
	 * 验证所有的类都是Class类的实例
	 * @throws ClassNotFoundException  
	 * return:void
	 */
	public static void demo2() throws ClassNotFoundException{
		
		//定义两个类型都未知的Class，设置初值为null，看看如何给他们赋值成person类
		Class<?> class1 = null;
		Class<?> class2 = null;
		
		class1  = Class.forName("com.hww.Reflect.Person");
		System.out.println("写法1，包名：" + class1.getPackage().getName() + ",完整类名：" + class1.getName());
		
		class2 = Person.class;
		System.out.println("写法2，包名：" + class2.getPackage().getName() + "完整类名：" + class2.getName());
	}
	
	/**
	 * 
	 * demo3:通过反射机制，用Class创建类对象，这也就是反射存在的意义。
	 *   void
	 * @throws ClassNotFoundException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	public static void demo3() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
		Class<?> class1 = null;
		class1 = Class.forName("com.hww.Reflect.Person");
		
		Person person = (Person)class1.newInstance();
		person.setName("huangwenwei");
		person.setAge(100);
		System.out.println(person.getName() + "," + person.getAge());
	}
	
	/**
	 * demo4：通过反射机制得到一个类的构造函数，并实现创建带参数的实例对象
	 *   void
	 * @throws ClassNotFoundException 
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	public static void demo4() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		Class<?> class1 = null;
		Person person1 = null;
		Person person2 = null;
		
		class1 = Class.forName("com.hww.Reflect.Person");
		Constructor<?>[] constructors = class1.getConstructors();
		
		person1 = (Person)constructors[0].newInstance();
		person1.setName("huangwenyi");
		person1.setAge(20);
		
		System.out.println(person1.getName() + "," + person1.getAge());
		person2 = (Person)constructors[1].newInstance(21,"huangxiaosan");
		System.out.println(person2.getName() + "," + person2.getAge());
	}
	
	/**
	 * demo5：通过反射机制操作成员变量,set和get
	 * @throws ClassNotFoundException
	 * @throws InstantiationException
	 * @throws IllegalAccessException  void
	 * @throws SecurityException 
	 * @throws NoSuchFieldException 
	 */
	public static void demo5() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException{
		Class<?> class1 = Class.forName("com.hww.Reflect.Person");
		Object obj = class1.newInstance();
		Field personNameField = class1.getDeclaredField("name");
		personNameField.setAccessible(true);	//取消访问检查
		personNameField.set(obj, "小虎");
		System.out.println("修改属性之后得到属性变量的值：" + personNameField.get(obj));
	}
	
	/**
	 * 通过反射机制得到类的一些属性：继承的接口、方法信息、成员信息、类型等
	 *   void
	 * @throws ClassNotFoundException 
	 */
	public static void demo6() throws ClassNotFoundException{
		Class<?> class1 = Class.forName("com.hww.Reflect.SuperMan");
		
		//取得父类名称
		Class<?>superclass = class1.getSuperclass();
		System.out.println("superMan类的父类名称：" + superclass.getName());
		
		Field[] fields = class1.getDeclaredFields();
		for(int i = 0;i<fields.length;i++){
			System.out.println("类中的成员" + i + ": " + fields[i]);
		}
		
		//取得方法
		Method[] methods = class1.getDeclaredMethods();
		for(int i=0;i<methods.length;i++){
			System.out.println("取得superMan类的方法" + i +":");
			System.out.println("函数名：" + methods[i].getName());
			System.out.println("函数返回类型：" + methods[i].getReturnType());
			System.out.println("函数修饰符：" + Modifier.toString(methods[i].getModifiers()));
			System.out.println("函数代码写法：" + methods[i]);
		}
		
		//取得类实现的接口，因为接口类也属于Class,所以得到接口中的方法跟得到类的方法一样。
		Class<?> interfaces[] = class1.getInterfaces();
		for(int i=0;i<interfaces.length;i++){
			System.out.println("实现的接口类名：" + interfaces[i].getName());
		}
	}
	
	/**
	 * 通过Java反射机制调用类方法
	 * @throws ClassNotFoundException  void
	 * @throws SecurityException 
	 * @throws NoSuchMethodException 
	 * @throws InstantiationException 
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 */
	public static void demo7() throws ClassNotFoundException, NoSuchMethodException,  IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException{
		Class<?> class1 = Class.forName("com.hww.Reflect.SuperMan");
		
		System.out.println("调用无参方法fly():");
		Method method = class1.getMethod("fly");
		method.invoke(class1.newInstance());
		
		System.out.println("调用有参方法walk(int m )");
		method = class1.getMethod("walk", int.class);
		method.invoke(class1.newInstance(),100);
	}
	
	public static void demo8() throws ClassNotFoundException{
		Class<?> class1 = Class.forName("com.hww.Reflect.Person");
		String name = class1.getClassLoader().getClass().getName();
		System.out.println("类加载器名：" + name);
	}
}
